﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Xml.Serialization;
using System.Threading;
using System.Web;
using System.Net.Cache;
using CommonTools;

namespace BusinessCloud
{
    public partial class MainForm : Form
    {
        HttpListener listerner = null;
        bool isRun = true;
        byte[] buffer = null;
        string m_BusinessUrl = "http://cloud.diantivideo.com:6500/"; //必须以斜杠结束
        string m_AnychatUrl = "http://business.anychat.cn/gateway";

        public delegate void LogDelegate(string text);
        public void log(string msg)
        {
            if (rtb_message.InvokeRequired)
            {
                this.BeginInvoke(new LogDelegate(log), new object[] { msg });
            }
            else
            {
                Log.WriteLog(msg);
                
                if (rtb_message.Lines.Length > 500)
                {
                    rtb_message.Text = rtb_message.Text.Substring(rtb_message.Text.Length / 2);
                }
                string dt = DateTime.Now.ToLongTimeString();
                rtb_message.AppendText(dt + " " + msg + "\n");
                rtb_message.SelectionStart = rtb_message.Text.Length;
                rtb_message.ScrollToCaret();
            }

        }
        public MainForm()
        {
            InitializeComponent();
            //在timer里会延时初始化程序
        }

        //延时初始化程序
        private void Init()
        {
            InitWebService(); //初始化webservice连接程序

            //启动网络监听线程
            Thread thread = new Thread(StartServer);
            thread.Start();
        }

        void StartServer()
        {
            try
            {
                buffer = new byte[10240];
                listerner = new HttpListener();
                {
                    while (isRun)
                    {
                        try
                        {
                            listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问
                            listerner.Prefixes.Add(m_BusinessUrl);

                            listerner.Start();
                        }
                        catch (Exception ex)
                        {
                            log("未能成功连接服务器：" + ex.StackTrace);
                            listerner = new HttpListener();
                            continue;
                        }
                        break;
                    }
                    log("服务器启动成功");

                    int maxThreadNum, portThreadNum;

                    //线程池
                    int minThreadNum;
                    ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
                    ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
                    Console.WriteLine("最大线程数：{0}", maxThreadNum);
                    Console.WriteLine("最小空闲线程数：{0}", minThreadNum);
                    log("等待客户连接中。。。。");
                    while (isRun)
                    {
                        //等待请求连接
                        //没有请求则GetContext处于阻塞状态
                        HttpListenerContext ctx = listerner.GetContext();

                        ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc), ctx);
                    }
                    log("服务器停止");
                }
            }
            catch (Exception e)
            {
                log("服务器停止");
                log(e.Message);
            }
        }

        void TaskProc(object o)
        {
            HttpListenerContext ctx = (HttpListenerContext)o;
            HttpListenerRequest request = ctx.Request;
            int iLen = (int)request.ContentLength64;
            request.InputStream.Read(buffer, 0, iLen);

            ctx.Response.StatusCode = 200;//设置返回给客服端http状态代码

            string AbsolutePath = ctx.Request.Url.AbsolutePath;
            if (!String.IsNullOrEmpty(AbsolutePath))
                AbsolutePath = AbsolutePath.Substring(1);
            if (String.IsNullOrEmpty(AbsolutePath))
                AbsolutePath = ctx.Request.QueryString["method"];

            string timestamp = ctx.Request.QueryString["timestamp"];
            string appid = ctx.Request.QueryString["appid"];
            string signtype = ctx.Request.QueryString["signtype"];
            string signstr = ctx.Request.QueryString["signstr"];
            string body = Encoding.GetEncoding("UTF-8").GetString(buffer, 0, iLen);

            //进行处理
            log("---------- TaskProc ----------");
            log("url:" + ctx.Request.Url.ToString());
            log("AbsolutePath:" + AbsolutePath);
            log("timestamp:" + timestamp);
            log("appid:" + appid);
            log("signtype:" + signtype);
            log("signstr:" + signstr);
            log("body:" + body);
            ParseNotifyBody(AbsolutePath, body);            

            //使用Writer输出http响应代码
            using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream))
            {
                writer.Write("处理结果");
                writer.Close();
                ctx.Response.Close();
            }
        }

        private void stop()
        {
            isRun = false;
            if (listerner != null)
                listerner.Stop();

            if (udpServer != null)
                udpServer.close();
        }

        private string GetJsonValue(string item, string json)
        {
            string value = "";

            //取出子项
            int b = json.IndexOf(item);
            if (b < 0)
                return value;
            b += item.Length + 1;

            int e = json.IndexOf(",", b);
            if (e < 0)
                e = json.Length;
            //log("b,e:" + b + "," + e);
            value = json.Substring(b, e - b);

            //从子项中取出值
            b = value.IndexOf(":");
            if (b < 0)
                b = 0;
            value = value.Substring(b + 1).Trim();

            //去掉前后引号
            b = value.IndexOf("\"");
            e = value.IndexOf("\"",b+1);
            if (e < 0)
                e = -1;
            if(b>=0)
            {
                if(e>0)
                    value = value.Substring(b + 1,e-b-1).Trim();
                else
                    value = value.Substring(b + 1).Trim();
            }

            return value;
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {

            Console.WriteLine(cs_common.getMD5Hash32("transbuffer&FD9C295F-A435-49AC-A021-DAE55DF747B8&20161219174942&sqgyms2rsdz3n3ix88hhge2biw88yno1"));
            stop();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            stop();
        }

        private bool PostData(string sUrl, string sPostData)
        {
            log("PostData:url=" + sUrl);
            log("PostData:body=" + sPostData);

            Encoding myEncoding = Encoding.UTF8;
            HttpWebRequest request;

            Console.WriteLine(string.Format("{0} {1}", sUrl, DateTime.Now.ToString("g")));
            try
            {
                // init
                request = HttpWebRequest.Create(sUrl) as HttpWebRequest;
                request.Method = "POST";
                request.Accept = "*/*";
                request.KeepAlive = false;
                request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                //request.ContentType = "application/x-www-form-urlencoded";
                request.ContentType = "application/json;charset=UTF-8";
                request.ContentLength = sPostData.Length;

                byte[] bufPost = myEncoding.GetBytes(sPostData);
                request.ContentLength = bufPost.Length;
                Stream newStream = request.GetRequestStream();
                newStream.Write(bufPost, 0, bufPost.Length);
                newStream.Flush();
                newStream.Close();

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                string encoding = response.ContentEncoding;
                if (encoding == null || encoding.Length < 1)
                {
                    encoding = "UTF-8"; //默认编码  
                }
                log("Response.ContentType:" + response.ContentType);
                string status = response.StatusCode.ToString();
                log("Response StatusCode：" + status);

                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
                string retString = reader.ReadToEnd();
                log("Response：" + retString);
                return true;
            }
            catch (Exception ex)
            {
               log("未能成功连接服务器：" + ex.StackTrace);
            }
            return false;
        }

        private string MakeUrl(string Method)
        {
            string timestamp = cs_common.GetDateTimeStr();
            string key = Method + "&FD9C295F-A435-49AC-A021-DAE55DF747B8&" + timestamp + "&sqgyms2rsdz3n3ix88hhge2biw88yno1";

            string s = m_AnychatUrl;
            s += "?method=" + Method;
            s += "&timestamp=" + timestamp;
            s += "&appid=FD9C295F-A435-49AC-A021-DAE55DF747B8";
            s += "&signtype=MD5";
            s += "&signstr=" + cs_common.getMD5Hash32(key);

            return s;
        }
        private void buttonPost_Click(object sender, EventArgs e)
        {
            SendMsgToUser(-514, "hello");
            /*
            string sUrl = MakeUrl("transbuffer");
            string sData = "\"appguid\" : \"AB3DE7E9-6D84-462F-ABEE-AB63212B6643\",\"loginipaddr\" : \"192.168.1.100\",\"logintime\" : \"20161012214259\",\"strparam\" : \"\",\"userflags\" : 0,\"userid\" : -3,\"userlever\" : 0,\"username\" : \"trew\"";
            PostData(sUrl, sData);
             */
        }

        private void ParseNotifyBody(string method, string body)
        {
            log("***** ParseNotifyBody：" + method);
            int userId = cs_common.String2Int(GetJsonValue("userid", body));
            string userName = GetJsonValue("username", body);

            log("userid:" + userId);
            log("username:" + userName);

            switch (method)
            {
                case "userlogin_notify":
                    {
                        OnlineUsers.Add(userId, userName); //登录时，加入在线用户列表
                        txtOnline.Text = OnlineCount().ToString();
                        listUsers.Items.Add("(" + userId + ")" + userName);

                        break;
                    }
                case "userlogout_notify":
                    {
                        listUsers.Items.Remove("(" + userId + ")" + userName);
                        OnlineUsers.Remove(userId); //注销时，移出在线用户列表
                        txtOnline.Text = OnlineCount().ToString();

                        break;
                    }
                case "recordsnapshot_notify":
                    {
                        log("recordfilename:" + GetJsonValue("recordfilename", body));
                        log("flags:" + GetJsonValue("flags", body));

                        break;
                    }
                case "transbuffer_notify":
                    {
                        string msg=cs_common.DecodeBase64(GetJsonValue("databuf", body));
                        log("datasize:" + GetJsonValue("datasize", body));
                        log("databuf:" + msg);

                        ProcessMessage(userId, msg);
                        break;
                    }
                case "transfile_notify":
                    {
                        log("userid:" + GetJsonValue("userid", body));
                        log("username:" + GetJsonValue("username", body));

                        log("filename:" + GetJsonValue("filename", body));
                        log("pathname:" + GetJsonValue("pathname", body));
                        log("filesize:" + GetJsonValue("filesize", body));

                        break;
                    }
                case "videocall_notify":
                    {
                        log("srcuserid:" + GetJsonValue("srcuserid", body));
                        log("srcusername:" + GetJsonValue("srcusername", body));
                        log("taruserid:" + GetJsonValue("taruserid", body));
                        log("tarusername:" + GetJsonValue("tarusername", body));

                        break;
                    }
                case "textmsg_notify":
                    {
                        log("srcuserid:" + GetJsonValue("srcuserid", body));
                        log("srcusername:" + GetJsonValue("srcusername", body));
                        log("taruserid:" + GetJsonValue("taruserid", body));
                        log("tarusername:" + GetJsonValue("tarusername", body));

                        log("msglen:" + GetJsonValue("msglen", body));
                        log("textmsg:" + GetJsonValue("textmsg", body));

                        break;
                    }
            }

        }

        int iTimerCnt = -1;
        private void timer1_Tick(object sender, EventArgs e)
        {
            iTimerCnt++;

            if (iTimerCnt == 0)
                Init();
            else if (iTimerCnt > 1000)
                iTimerCnt = 0;
        }

    }
}
